# consumers是websocket消费者，它继承自AsyncWebsocketConsumer（异步websocket消费者），用于处理websocket请求。
# 为了处理高并发问题，采用异步
import json
# 异步websocket消费者
from channels.generic.websocket import AsyncWebsocketConsumer
from chat.models import Message ,User
# django的timezone模块,用于处理时间相关操作
from django.utils import timezone
# sync_to_async和async_to_async的区别是：sync_to_async是将同步代码转换为异步代码，而async_to_sync是将异步代码转换为同步代码。
from asgiref.sync import sync_to_async
# uuid模块，用于生成唯一的标识符
import uuid

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.user_uuid = self.scope['url_route']['kwargs']['user_uuid']
        self.room_group_name = f"user_{self.user_uuid}"

        # 加入房间组
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # 离开房间组
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    # 从 WebSocket 接收消息
    async def receive(self, text_data):
        data = json.loads(text_data)
        message = data['message']

        # 保存消息到数据库
        await self.save_message(self.user_uuid, message, is_customer=False)

        # 发送消息到房间组
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message,
                'is_customer': False,
            }
        )

    # 从房间组接收消息
    async def chat_message(self, event):
        message = event['message']
        is_customer = event['is_customer']

        # 发送消息到 WebSocket
        await self.send(text_data=json.dumps({
            'message': message,
            'is_customer': is_customer,
        }))

    @sync_to_async
    def save_message(self, user_uuid, message, is_customer):
        user, created = User.objects.get_or_create(uuid=user_uuid, defaults={
            'username': f"User_{user_uuid}",
            'is_customer_service': False
        })
        Message.objects.create(user=user, content=message, is_customer=is_customer)

